import React, { useMemo, useState, useEffect } from 'react';
import { loc_str, FindBarBase, export_csv_file, useCmd, ErrView, WaitUmd,
    filter_row, obj_str, useHigh, MainView, Btn, GridTable, urlTb, is_empty, for_obj, loc } from 'sui';
import { utc_offset } from 'cache';
import { urlWork } from 'nui';
import { get_init, cell_col, cell_para, cell_row } from './cmd';

const TraceView = ({ mod }) => {
    const [name, setName] = useState();
    const [sn, setSn] = useState();
    const [col, setCol] = useState();
    const [para, setPara] = useState();
    const [mtype, setType] = useState(null);
    const [main, setMain] = useState(null);
    const [opt_find, optFind] = useState();
    const umd = useCmd(null, "trace");
    const [high] = useHigh(140, 100);

    useEffect(() => get_init(optFind), []);

    useEffect(() => {
        urlWork(null, "cache/get", {uid: mod},
            r => {
                setName(obj_str(r, "name"));
                setSn(obj_str(r, "uid"));
            }, e => {
                setSn("");
                setName("");
            });
    }, [mod]);

    useEffect(() => {
        if (!sn) {
            return;
        }

        urlTb(null, "col", {n: sn},
            r => {
                setCol(cell_col(r));
                setType(r);
                setPara(cell_para(r));
            }, e => {
                setPara(null);
                setCol(null);
                setType(null);
            });
    }, [sn]);

    const get_val = (k, v) => {
        if (is_empty(mtype)) {
            return v;
        }

        const f = mtype.find(d => d === k);
        if (!f) {
            return v;
        }

        if (v === "true") {
            return true;
        }

        if (v === "false") {
            return false;
        }

        if (v.lastIndexOf(".") >= 0) {
            return parseFloat(v);
        }

        return parseInt(v, 10);
    };

    const hfind = (value) => {
        const utc = utc_offset();
        const opt = [];

        for_obj(value, (k, v) => {
            if (k === "t_start" || k === "t_end") {
                return;
            }

            if (!v) {
                return;
            }

            if (k === "time") {
                opt.push({ge: "time", v: loc_str(value["t_start"]), utc: utc});
                opt.push({le: "time", v: loc_str(value["t_end"]), utc: utc});
                return;
            }

            opt.push({eq: k, v: get_val(k, v)});
        });

        if (is_empty(opt)) {
            alert(loc("cmd_2"));
            return;
        }

        umd.startWait();

        urlTb(umd.endWait, "get",
            {
                n: sn,
                obj: "*",
                opt: {desc: true, and: opt}
            },
            r => {
                const data = r[sn]["data"];
                cell_row(data);

                setMain(data);
            },
            e => setMain(null));
    };

    const filteredRows = useMemo(() => {
        if (is_empty(main)) {
            return null;
        }

        const lst = [];
        for_obj(mtype, (k, v) => lst.push(k));

        return filter_row(main, lst, umd.filter);
    }, [mtype, main, umd.filter]);

    const TraceTable = () => {
        if (is_empty(main)) {
            return <ErrView err={loc("cmd_3")}/>;
        }

        return <GridTable col={col} row={filteredRows} high={high - 50}/>;
    };

    const hcsv = () => {
        if (is_empty(col)) {
            return;
        }

        const dcol = col.map(d => d.key);
        const drow = [];

        main.forEach(d => {
            const tmp = dcol.map(k => d[k]);
            if (is_empty(tmp)) {
                return;
            }

            drow.push(tmp);
        });

        export_csv_file(`${mod}_data`, col.map(d => d.name), drow);
    };

    const Right = () => {
        return (
            <div className="inline-flex items-center">
                <Btn hcmd={hcsv} className="ml-4">{loc("dc")}</Btn>
            </div>
        );
    };

    const Left = () => {
        return <div>{`${sn} ( ${name} )`}</div>
    };

    const hclear = () => get_init(optFind);

    const getCtl = () => {
        return {
            ctl: [
                {sn: "psn", name: loc("cph")},
                {sn: "time", name: loc("cmd_8"), ctl: "IkFindDate", start: "t_start", end: "t_end"},
            ],
            para: para,
        };
    };

    return (
        <MainView>
            <FindBarBase left={<Left/>} right={<Right/>} hcmd={hfind} data={getCtl()} hclear={hclear} cur={opt_find} hfilter={umd.setFilter}/>
            <TraceTable/>
            <WaitUmd umd={umd}/>
        </MainView>
    );
};

export {TraceView};
